package com.bupt.ilink.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bupt.ilink.controller.DatasetController;
import com.bupt.ilink.entity.*;
import com.bupt.ilink.mapper.DatasetTagsMapper;
import com.bupt.ilink.service.*;
import com.bupt.ilink.mapper.DatasetMetadataMapper;
import com.bupt.ilink.utils.SnowflakeIdGenerator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.IdGenerator;
import org.springframework.web.multipart.MultipartFile;

import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author zhangbo
 * @description 针对表【dataset_metadata】的数据库操作Service实现
 * @createDate 2024-07-25 10:53:08
 */
@Service
public class DatasetMetadataServiceImpl extends ServiceImpl<DatasetMetadataMapper, DatasetMetadata>
        implements DatasetMetadataService{

    @Autowired
    private DatasetMetadataMapper datasetMetadataMapper;

    @Autowired
    private DatasetTagsService datasetTagsService;

    @Autowired
    private DatasetAssociationUserService datasetAssociationUserService;

    @Autowired
    private DatasetFavoriteService datasetFavoriteService;

    @Autowired
    private DatasetFilesService datasetFilesService;

    @Autowired
    private MinioService minioService;

    private static final Logger logger = LoggerFactory.getLogger(DatasetController.class);

    private final SnowflakeIdGenerator idGenerator = new SnowflakeIdGenerator(1, 1);

    //  用户创建数据集
    @Override
    @Transactional
    public boolean createDataset(User user, DatasetRequest datasetProvide,
                                 List<MultipartFile> files){
        try{
            //更新DatasetMetadata类
            DatasetMetadata metadata = new DatasetMetadata();

            metadata.setDatasetId(idGenerator.nextId());
            long datasetId = metadata.getDatasetId();
            metadata.setName(datasetProvide.getDatasetName());
            metadata.setDescription(datasetProvide.getDatasetDescription());
            //如果是个人发布
            if(datasetProvide.getPersonalPublish()){
                metadata.setCreatorName(user.getUsername());
                metadata.setAccessLevel("person");
                //更新DatasetAssociationUser类
                DatasetAssociationUser associationUser = new DatasetAssociationUser();
                associationUser.setAssociationId(idGenerator.nextId());
                associationUser.setUserId(user.getUserId());
                associationUser.setDatasetId(datasetId);
                //如果选择公开
                if(datasetProvide.getIsPublic()){
                    associationUser.setAccessLevel("shared");
                }else{
                    //如果私有但团队内部可见
                    if(datasetProvide.getTeamSeen()){
                        associationUser.setAccessLevel("team");
                    }else{
                        associationUser.setAccessLevel("exclusive");
                    }
                }
                datasetAssociationUserService.save(associationUser);
            }
            metadata.setCreatedTime(new Date());
            metadata.setUpdatedTime(new Date());
            metadata.setStatus("pending_review");   //待审核状态
            //如果是团队发布
            if(datasetProvide.getTeamPublish()){
                metadata.setAccessLevel("team");
            }
            //存储数据集封面到MinIO的image文件夹
            MultipartFile datasetImageFile = files.get(0);
            String datasetImageName = datasetId + getFileExtension(datasetImageFile.getOriginalFilename());
            metadata.setImagePath("image/"+datasetId);
            minioService.uploadSingleFile("image",
                    datasetImageName, datasetImageFile);
            metadata.setClickNum(0L);
            metadata.setDownloadNum(0L);
            metadata.setShareNum(0L);
            metadata.setFavoriteNum(0L);
            metadata.setFromMinio(1);
//            datasetMetadataService.save(metadata);

            //  更新DatasetTags类
            // 保存 topicTag 到 dataset_tags
            saveTags(datasetProvide.getTopicTag(), datasetId);
            // 保存 jobTag 到 dataset_tags
            saveTags(datasetProvide.getJobTag(), datasetId);

            //  更新DatasetFiles类
            saveDatasetFiles(files.subList(1, files.size()), datasetId);


        }catch (Exception e){
            return false;
        }
        return false;
    }
    // 获取文件后缀的方法
    private String getFileExtension(String fileName) {
        if (fileName == null) {
            return "";
        }
        int dotIndex = fileName.lastIndexOf('.');
        return dotIndex == -1 ? "" : fileName.substring(dotIndex);
    }

    // 保存标签的方法
    private void saveTags(List<String> tags, Long datasetId) {
        if (tags != null && !tags.isEmpty()) {
            for (String tag : tags) {
                DatasetTags datasetTag = new DatasetTags();
                datasetTag.setTagId(idGenerator.nextId());
                datasetTag.setDatasetId(datasetId);
                datasetTag.setTag(tag);

                // 这里使用 MyBatis-Plus 保存到数据库中
                datasetTagsService.save(datasetTag);
            }
        }
    }
    //存储剩余文件到 MinIO 并保存到 DatasetFiles 表中
    private void saveDatasetFiles(List<MultipartFile> files, Long datasetId) {
        for (MultipartFile file : files) {
            try {
                // 生成新的文件 ID
                Long fileId = idGenerator.nextId();

                // 上传文件到 MinIO 的 files 文件夹
                String fileName = fileId + getFileExtension(file.getOriginalFilename());
                String filePath = "files/" + fileName;
                String fileUrl = minioService.uploadSingleFile("files", fileName, file);

                // 创建并保存 DatasetFiles 对象
                DatasetFiles datasetFile = new DatasetFiles();
                datasetFile.setFileId(fileId);
                datasetFile.setDatasetId(datasetId);
                datasetFile.setFilePath(filePath);
                datasetFile.setFileSize(file.getSize());
                datasetFile.setFileType(file.getContentType());
                datasetFile.setUploadedAt(new Date());

                datasetFilesService.save(datasetFile);
            } catch (Exception e) {
                logger.error("上传文件时出现错误: {}", file.getOriginalFilename(), e);
            }
        }
    }

    @Override
    public Set<String> getAllNames() {
        List<String> names = datasetMetadataMapper.getAllNames();
        return new HashSet<>(names);
    }

    public DatasetMetadata getById(String datasetId) {
        return datasetMetadataMapper.selectById(datasetId);
    }

    @Override
    public List<DatasetMetadata> getDatasetsByKeywords(String keywords) {
        return baseMapper.selectByKeywords(keywords);
    }

    @Override
    @Transactional
    public boolean deleteDataset(Long datasetId) {
        try {
            // 删除与 datasetId 关联的 DatasetAssociationUser
            QueryWrapper<DatasetAssociationUser> associationUserQuery = new QueryWrapper<>();
            associationUserQuery.eq("dataset_id", datasetId);
            datasetAssociationUserService.remove(associationUserQuery);

            // 删除与 datasetId 关联的 DatasetFavorite
            QueryWrapper<DatasetFavorite> favoriteQuery = new QueryWrapper<>();
            favoriteQuery.eq("dataset_id", datasetId);
            datasetFavoriteService.remove(favoriteQuery);

            // 删除与 datasetId 关联的 DatasetFiles
//            QueryWrapper<DatasetFiles> filesQuery = new QueryWrapper<>();
//            filesQuery.eq("dataset_id", datasetId);
//            datasetFilesService.list(filesQuery).forEach(datasetFile -> {
//                // 删除 MinIO 中对应的文件
//                minioService.deleteFile(datasetFile.getFilePath());
//            });
//            datasetFilesService.remove(filesQuery);


            // 删除与 datasetId 关联的 DatasetTags
            QueryWrapper<DatasetTags> tagsQuery = new QueryWrapper<>();
            tagsQuery.eq("dataset_id", datasetId);
            datasetTagsService.remove(tagsQuery);



            // 最后删除 DatasetMetadata
            datasetMetadataMapper.deleteById(datasetId);

            return true;
        } catch (Exception e) {
            logger.error("删除数据集时出现错误", e);
            return false;
        }
    }

    @Override
    public List<DatasetMetadata> getDatasetsByIds(List<Long> datasetIds) {
        return baseMapper.selectByDatasetIds(datasetIds);
    }

    @Override
    public List<DatasetMetadata> getAllPublicDatasets() {
        return lambdaQuery().eq(DatasetMetadata::getAccessLevel, "public").list();
    }
    @Override
    public IPage<DatasetMetadata> getPublicDatasetsByPage(Page<DatasetMetadata> page) {
        return lambdaQuery().eq(DatasetMetadata::getAccessLevel, "public").page(page);
    }

    @Override
    public long count() {
        // 使用查询来获取 DatasetMetadata 的总数
        return datasetMetadataMapper.selectCount(null);
    }

    @Override
    public void incrementDownloadNum(Long datasetId) {
        baseMapper.incrementDownloadNum(datasetId);
    }

    @Override
    public void incrementShareNum(Long datasetId) {
        baseMapper.incrementShareNum(datasetId);
    }
    @Override
    public void incrementClickNum(Long datasetId) {
        baseMapper.incrementClickNum(datasetId);
    }
    @Override
    public void incrementFavoriteNum(Long datasetId) {
        baseMapper.incrementFavoriteNum(datasetId);
    }
}



